/*================================================================================
*
*
*                                   
*
*
* 项目名称: mcp2515-spi-can-demo
* 文件名称: mcp2515_can_app.c
* 创建日期: 21-02-03
* 文件描述: 
*
================================================================================*/
#include "main.h"
#include "gpio.h"
#include "mcp2515.h"
#include "RGB_LED.h"
#include "spi.h"
#include "DBG_PR.h"

#include "mcp2515_can_comm.h"

//-private code------------------------------------------------------------------
static void MCP2515CAN_TxMsg(void);

//-private data------------------------------------------------------------------
static McpCanFrm_t s_MsgRx;
static uint8_t flgRxOk, flgTxTickOk=1;

//-public data-------------------------------------------------------------------

/********************************************************************************
*函数功能: 
    初始化MCP2515 CAN功能 
    125kbps速率。1TQ=1000ns，晶振8MHz则8分频 PRS+PS1=5TQ PS2=2TQ
*修改记录: 
*日期:                作者:                摘要:
      21-02-03             YummoShin            Create
********************************************************************************/
void InitMCP2515CAN(void)
{
    McpBitTime_t BitTime=
    {
        .u8BRP = MCP2515_CLKPRE2,
        .u8PRSEG = 6-1,
        .u8PHSEG1 = 7-1,
        .u8PHSEG2 = 2-1,
        .u8SJW = 1-1
    };
    McpRxFlt_t Filter={.u16SID=0x01, .u8EXIDE=1, .u32EID=0x01};
    McpRxMsk_t Mask={.u16SID=0x00, .u32EID=0x00};

    __HAL_SPI_ENABLE(&hspi2);

    MCP2515Reset();
    HAL_Delay(5);
    MCP2515SetMode(MCP2515_REQOP_CONFIG);
    HAL_Delay(5);

    MCP2515CfgBitTime(&BitTime); //配置CAN速率
    MCP2515SetRxFlt(MCP2515_RXF0, &Filter); //配置验收器
    MCP2515SetRxMsk(MCP2515_RXM0, &Mask);
    MCP2515EnableOSM(); //配置单触发发送模式

    MCP2515SetMode(MCP2515_REQOP_NORMAL); //配置正常工作模式
//    MCP2515SetMode(MCP2515_REQOP_LOOPBACK);
}

/********************************************************************************
*函数功能: 
    CAN通讯处理主函数
*修改记录: 
*日期:                作者:                摘要:
      21-02-03             YummoShin            Create
********************************************************************************/
void ProcessMCP2515CAN_Comm(void)
{
    static uint32_t u32Tick;
    RgbLed_t led;

    //定时发送报文
    if(flgTxTickOk)
    {
        flgTxTickOk = 0;
        MCP2515CAN_TxMsg();
        u32Tick = HAL_GetTick();
        DBG_PR("send message\n");
    }
    if( (HAL_GetTick()-u32Tick) >=500 )
    {
        flgTxTickOk = 1;
    }


    if(flgRxOk)
    {
        flgRxOk = 0;
        led.u8R = s_MsgRx.u8Data[0];
        led.u8G = s_MsgRx.u8Data[1];
        led.u8B = s_MsgRx.u8Data[2];
        led.u8L = s_MsgRx.u8Data[3];

        RgbLedCtrl(&led);

        DBG_PR("get message\n");
    }
}

/********************************************************************************
*函数功能: 
    CAN通讯处理测试函数
*修改记录:
*日期:                作者:                摘要:
      22-10-06             YummoShin            Create
********************************************************************************/
void TestMCP2515CAN_Comm(void)
{

    /* 接口函数测试 ok
    uint8_t u8DATA[3]={0x03, CNF3};

    MCU_SPI_CTRL_CS_LO();

    MCU_SPI_WR_BURST_FUNTION(u8DATA, 2);
    MCU_SPI_READ_FUNCTION(u8DATA, 3);

    MCU_SPI_CTRL_CS_HI();

    DBG_PR("data receive CF3: 0x%X, CF2: 0x%X, CF1: 0x%X\n", u8DATA[0], u8DATA[1], u8DATA[2]);
    */

    /* 读取CANCTRL ok
    uint8_t u8Data[3]={0x03, CANCTRL};

    MCU_SPI_CTRL_CS_LO();

    MCU_SPI_WR_BURST_FUNTION(u8Data, 2);
    MCU_SPI_READ_FUNCTION(u8Data, 1);

    MCU_SPI_CTRL_CS_HI();

    DBG_PR("read CANCTRL: 0x%X\n", u8Data[0]);
    */

    McpCanFrm_t CanMsg=
    {
        .u16SID=1,
        .u8DLC=5,
    };
    CanMsg.u8Data[0]=g_LedState.u8R;
    CanMsg.u8Data[1]=g_LedState.u8G;
    CanMsg.u8Data[2]=g_LedState.u8B;
    CanMsg.u8Data[3]=g_LedState.u8L;
    CanMsg.u8Data[4]=g_LedState.flgAdj;

    MCP2515DisableIT(MCP2515_IT_RX0); //禁止MCP2515中断

    uint8_t u8DATA[10]={0x03, CANINTE };
    MCU_SPI_CTRL_CS_LO();
    MCU_SPI_WR_BURST_FUNTION(u8DATA, 2);
    MCU_SPI_READ_FUNCTION(u8DATA, 1);
    MCU_SPI_CTRL_CS_HI();
    DBG_PR("read CANINTE: 0x%X\n", u8DATA[0]);


    MCP2515WrMsgToBuf(MCP2515_TXB0, &CanMsg); //装载报文

    u8DATA[0] = 0x03; u8DATA[1] = TXB0SIDH;
    MCU_SPI_CTRL_CS_LO();
    MCU_SPI_WR_BURST_FUNTION(u8DATA, 2);
    MCU_SPI_READ_FUNCTION(u8DATA, 10);
    MCU_SPI_CTRL_CS_HI();
    DBG_PR("read start TXB0SIDH: 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X\n",
        u8DATA[0], u8DATA[1], u8DATA[2], u8DATA[3], u8DATA[4], u8DATA[5], u8DATA[6], u8DATA[7], u8DATA[8], u8DATA[9]);

    MCP2515RTS(MCP2515_TXB0); //请求发送
    u8DATA[0] = 0x03; u8DATA[1] = TXB0CTRL;
    MCU_SPI_CTRL_CS_LO();
    MCU_SPI_WR_BURST_FUNTION(u8DATA, 2);
    MCU_SPI_READ_FUNCTION(u8DATA, 1);
    MCU_SPI_CTRL_CS_HI();
    DBG_PR("read TXB0CTRL: 0x%X\n", u8DATA[0]);

    MCP2515EnableIT(MCP2515_IT_RX0); //打开MCP2515中断
    u8DATA[0] = 0x03; u8DATA[1] = CANINTE;
    MCU_SPI_CTRL_CS_LO();
    MCU_SPI_WR_BURST_FUNTION(u8DATA, 2);
    MCU_SPI_READ_FUNCTION(u8DATA, 1);
    MCU_SPI_CTRL_CS_HI();
    DBG_PR("read CANINTE: 0x%X\n", u8DATA[0]);
}

/********************************************************************************
*函数功能:
    单触发模式发送,保证实时性
*修改记录: 
*日期:                作者:                摘要:
      21-02-03             YummoShin            Create
********************************************************************************/
static void MCP2515CAN_TxMsg(void)
{
    McpCanFrm_t CanMsg=
    {
        .u16SID=1,
        .u8DLC=5,
        .u8Data[0]=g_LedState.u8R,
        .u8Data[1]=g_LedState.u8G,
        .u8Data[2]=g_LedState.u8B,
        .u8Data[3]=g_LedState.u8L,
        .u8Data[4]=g_LedState.flgAdj
    };

//    MCP2515DisableIT(MCP2515_IT_RX0); //禁止MCP2515中断
    MCP2515SetTxPri(MCP2515_TXB0, MCP2515_TXP_LVL3);
    MCP2515WrMsgToBuf(MCP2515_TXB0, &CanMsg); //装载报文
    MCP2515RTS(MCP2515_TXB0); //请求发送

//    MCP2515EnableIT(MCP2515_IT_RX0); //打开MCP2515中断
}

/********************************************************************************
*函数功能: 
    MCP2515中断请求,使用外部中断,配置为接收中断,只处理接收中断
*修改记录: 
*日期:                作者:                摘要:
      21-02-03             YummoShin            Create
********************************************************************************/
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
    (void)GPIO_Pin;
    MCP2515GetMsg(MCP2515_RXB0, &s_MsgRx); //获取接收的数据,设置标志位
    flgRxOk = 1;
    MCP2515ClrITFLG(MCP2515_IT_RX0); //清除中断标志位
}
